 /*    
  * Copyright (c) 2022, SHANGHAI FUDAN MICROELECTRONICS GROUP CO., LTD.(FUDAN MICROELECTRONICS./ FUDAN MICRO.)    
  * All rights reserved.    
  *    
  * Processor:                   FM33LG0xxA    
  * http:                        http://www.fmdevelopers.com.cn/    
  *    
  * Redistribution and use in source and binary forms, with or without    
  * modification, are permitted provided that the following conditions are met    
  *    
  * 1. Redistributions of source code must retain the above copyright notice,    
  *    this list of conditions and the following disclaimer.    
  *    
  * 2. Redistributions in binary form must reproduce the above copyright notice,    
  *    this list of conditions and the following disclaimer in the documentation    
  *    and/or other materials provided with the distribution.    
  *    
  * 3. Neither the name of the copyright holder nor the names of its contributors    
  *    may be used to endorse or promote products derived from this software    
  *    without specific prior written permission.    
  *    
  * 4. To provide the most up-to-date information, the revision of our documents     
  *    on the World Wide Web will be the most Current. Your printed copy may be      
  *    an earlier revision. To verify you have the latest information avaliable,    
  *    refer to: http://www.fmdevelopers.com.cn/.    
  *    
  * THIS SOFTWARE IS PROVIDED BY FUDAN MICRO "AS IS" AND ANY EXPRESSED     
  * ORIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES     
  * OF MERCHANTABILITY NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE    
  * ARE DISCLAIMED.IN NO EVENT SHALL FUDAN MICRO OR ITS CONTRIBUTORS BE LIABLE     
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL     
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS     
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER    
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,     
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY WAY OUT OF THE     
  * USE OF THIS SOFTWARE, EVEN IF ADVISED OFTHE POSSIBILITY OF SUCH DAMAGE.    
 */    
#include "IF_GxwLib.h"
#include "GpioAbst.h"
#include "IF_Switch.h"
#include "main.h"

#define SLLEP_TIMEOUT_TIME  200
static uint8 SleepFlag = 0;
static uint16 SleepTimeout = 0;
/**
  * @brief  GPIO中断函数
  * @param  void
  * @retval None
  */
void EXTI_DAC_IRQHandler(void)
{
    uint32_t triggerEdge;
    uint32_t extiFlag;
    
    /* EXTI PB8处理 */
    triggerEdge = FL_EXTI_GetTrigEdge(KL15_EXTI_PORT, KL15_EXTI_PIN);
    extiFlag = FL_EXTI_IsActiveFlag(KL15_EXTI_PORT, KL15_EXTI_PIN);
    if ((FL_GPIO_EXTI_TRIGGER_EDGE_DISABLE != triggerEdge) && (0x01 == extiFlag))
    {
        SleepFlag = 0;
        /* 清除中断标识 */
        FL_EXTI_ClearFlag(KL15_EXTI_PORT, KL15_EXTI_PIN);
        
        /* 唤醒 */
        NVIC_DisableIRQ(EXTI_DAC_IRQn); /* 关闭中断 */
		(void)SelXTHFToPLL(&CMU_XTHF_Init_Data, &CMU_PLL_Init_Data);                /* 唤醒后主频时钟重新切换为XTHF */
		/* CANFD外设初始化 */
        (void)Can_Init(CANFD1);

        //发送为空时 关闭can 不然休眠前后会发一帧故障 
        IF_GpioAbs_HallPwrCtrl(ON);
        IF_GpioAbs_UbdPwrAdcDetCtrl(ON);
        IF_GpioAbs_CanPwrCtrl(ON);
    }
}
/**
  * @brief  外部引脚中断初始化
  * @param  void
  * @retval void
  */
void GPIO_interrupt_init(void)
{
    FL_GPIO_InitTypeDef GPIO_InitStruct = {0};
    FL_EXTI_CommonInitTypeDef extiCommonInitStruct = {0};
    FL_EXTI_InitTypeDef extiInitStruct = {0};
    FL_NVIC_ConfigTypeDef InterruptConfigStruct;

    /* GPIO中断引脚设为输入 */
    GPIO_InitStruct.pin           = KL15_EXTI_PIN;
    GPIO_InitStruct.mode          = FL_GPIO_MODE_INPUT;
    GPIO_InitStruct.outputType    = FL_GPIO_OUTPUT_PUSHPULL;
    GPIO_InitStruct.pull          = FL_GPIO_PULLUP_ENABLE;
    GPIO_InitStruct.remapPin      = FL_GPIO_PINREMAP_FUNCTON0;
    GPIO_InitStruct.driveStrength = FL_GPIO_DRIVESTRENGTH_X3;     
    (void)FL_GPIO_Init(KL15_EXTI_PORT, &GPIO_InitStruct);

    /* EXTI中断采样时钟选择 */
    extiCommonInitStruct.clockSource = FL_CMU_EXTI_CLK_SOURCE_LSCLK;
    /* 休眠使能外部中断采样 */
    extiCommonInitStruct.EXTIOnSleep = FL_ENABLE;
    (void)FL_EXTI_CommonInit(&extiCommonInitStruct);

    /* 配置KL15引脚外部中断功能 */
    extiInitStruct.extiPinX    = KL15_EXTI_PIN;
    /* 使能数字滤波 */
    extiInitStruct.filter      = FL_ENABLE;
    /* 设置触发边沿模式 */
    extiInitStruct.triggerEdge = FL_GPIO_EXTI_TRIGGER_EDGE_FALLING;  
    (void)FL_EXTI_Init(KL15_EXTI_PORT, &extiInitStruct);  

    /* 清除中断标识 */
    FL_EXTI_ClearFlag(KL15_EXTI_PORT, KL15_EXTI_PIN);
    /* NVIC中断配置 */
    NVIC_DisableIRQ(EXTI_DAC_IRQn);    /* 关闭中断 */
    NVIC_SetPriority(EXTI_DAC_IRQn, 2);
    NVIC_EnableIRQ(EXTI_DAC_IRQn);     /* 开启中断 */
}

/**
  * @brief  DeepSleep初始化
  * @param  void
  * @retval None
  */
void GotoSleep(void)
{
    FL_PMU_SleepInitTypeDef LPM_InitStruct;
    
    LPM_InitStruct.deepSleep       = FL_PMU_SLEEP_MODE_NORMAL;
    LPM_InitStruct.powerMode       = FL_PMU_POWER_MODE_SLEEP_OR_DEEPSLEEP;
    LPM_InitStruct.wakeupFrequency = FL_PMU_RCHF_WAKEUP_FREQ_8MHZ;
    LPM_InitStruct.wakeupDelay     = FL_PMU_WAKEUP_DELAY_2US;
    FL_PMU_Sleep_Init(PMU, &LPM_InitStruct);
    /* 使能PDR */
    FL_RMU_PDR_Enable(RMU);  
    /* 使能BOR */
    FL_RMU_BOR_Enable(RMU);  
    /* 睡眠电源模式*/
    FL_PMU_SetLowPowerMode(PMU, FL_PMU_POWER_MODE_SLEEP_OR_DEEPSLEEP);
    /* 休眠 */
    (void)__WFI();
}

/**
  * @brief  IF_SleepMngTask_10ms休眠
  * @param  void
  * @retval None
  */
void IF_SleepMngTask_10ms(void)
{
	if(IF_GetSwitchState(IG_SIG_INDEX) == OFF)//KL15 OFF //初始化或唤醒时KL15电平状态为ON
	{
	    if(SleepTimeout <= SLLEP_TIMEOUT_TIME) 
	    {
			if(SleepTimeout == SLLEP_TIMEOUT_TIME) 
			{
				// GPIO_interrupt_init();//IF_WakeUp_Init(); //启动唤醒//
                ESC_214_Msg.ESC_214_RollingCounter = 0;
				SleepFlag = 0;
			}
	        SleepTimeout ++;
	    }
	    else
	    {
			SleepFlag++;//若在此之后出现KL15唤醒,在唤醒中断里清除SleepFlag
			IWDT_Clr();
			if((IF_GpioAbs_GetIgState() == OFF) && (SleepFlag > 0))
			{
                GPIO_interrupt_init();
				// while(FL_CAN_IsActiveFlag_BusBusy(CAN));//等待CAN空闲//
				/* 关所有功率输出 */
				IF_GpioAbs_CanPwrCtrl(OFF);
				IF_GpioAbs_HallPwrCtrl(OFF);
				IF_GpioAbs_UbdPwrAdcDetCtrl(OFF);
				FL_CMU_DisableIT_XTHFFail();//禁止XTHF错误中断//
				if(SleepFlag > 0) //在整个else里未进唤醒中断
                {
				    GotoSleep();
                }
			}
			else 
			{
				SleepFlag = 0;//退出睡眠清0
			}
	    }
	}
	else
	{
		SleepFlag = 0;
		NVIC_DisableIRQ(EXTI_DAC_IRQn);
		FL_EXTI_DeInit(KL15_EXTI_PORT, KL15_EXTI_PIN);/* 关中断 */
	    SleepTimeout = 0; 
		IF_GpioAbs_HallPwrCtrl(ON);
		IF_GpioAbs_UbdPwrAdcDetCtrl(ON);
		IF_GpioAbs_CanPwrCtrl(ON);
	}
}